CHAOS MUSIC COMPOSER - Moduł odtwarzający
|
| ||||||||||||||||||||||||||||||||
|
Do użycia nagranych utworów we własnych programach służy moduł odgrywający. Jak go nagrać opisałem w poprzednim rozdziale. Teraz zajmiemy się ogólnie jego budową i obsługą. Odgrywacz jest nagrany w formie ładowalnego pliku o strukturze DOSowej. Oznacza to, że można go załadować z poziomu DOSu lub COSu bezpośrednio pod adres podany w czasie jego nagrywania. Z pozimu BASICu nie jest to takie proste, lecz w programie przykładowym jest procedura uniwersalna ładująca pliki dosowe.
Na początku odgrywacza znajduje się krótka tablica skoków oraz zmienne, z których można odczytać głośność na poszczególnych kanałach. Pierwsze trzy bajty to skok do procedury inicjalizującej i odgrywającej używany z poziomu BASICu. Następnie mamy skok do procedury komunikacyjnej – używanej w ASSEMBLERZE. Trzeci z kolei jest skok do procedury taktującej używany z poziomu assemblera do odgrywania melodii. Następne trzy bajty to aktualna głośność poszczególnych ścieżek dźwiękowych. Specjalnego omówienia wymaga procedura komunikacji. Można ją wywołać z różnymi parametrami, co powoduje różnorakie reakcje. Parametry do tej procedury przekazuje się przy pomocy rejestrów A, X i Y. Reakcje procedury na różne parametry ilustruje tabelka:
Jak widać skok do procedury komunikacyjnej z różnymi wartościami akumulatora powoduje różne reakcje. W odróżnieniu od procedury taktującej (odgrywającej) do której należy skakać zawsze co 1/50 sekundy, obojętnie czy na przerwaniu, czy w pętli, do procedury komunikacyjnej skaczemy tylko gdy chcemy odgrywacza powiadomić co ma aktualnie robić. I tak możemy zażądać zagrania całej muzyczki o numerze podanym w X (1), lub tylko jej części począwszy od dowolnej pozycji numerowanej jak w CMC w oknie SONG. Przy odgrywaniu kilku muzyczek jednego songu (oddzielonych SHIFT B) w assemblerze numerujemy od 0. Można też wydobyć dźwięk tylko jednego instrumentu (3) (np. efektu strzału). Aktualnie grana muzyczka cichnie wtedy na odpowiednim kanale i jest wznawiana od następnego taktu. Wykonalna jest również zmiana tempa w trakcie grania utworu (4). Koniec odgrywania (5) różni się od przerwy (6) sposobem działania. Jeżeli użyjemy funkcji 6 to wszystkie instrumenty wybrzmią do końca. Kontynuacja (7) służy do ponownego włączenia przerwanej muzyczki od momentu końca. Inicjalizacja (8) służy do powiadomienia odgrywacza, gdzie powinien szukać danych songu i instrumentów (pliki z rozszerzeniem CMC). Najprostszy program odgrywający może wyglądać tak:
ldx <musadr ldy >musadr lda #$70 jsr play+3 inicjuj dane ldx #0 txa jsr play+3 graj song nr 0
*- pętla grająca loop lda 20 cmp 20 beq *-2
jsr play+6 taktuj
jmp loop
przy założeniu, że musadr jest adresem gdzie zaczynają się dane muzyczki, a play jest adresem modułu odtwarzającego.
Pozostało jeszcze do omówienia używanie odgrywacza z poziomu BASICu. Wbrew pozorom jest to proste. Wystarczy, by dane muzyczki i odgrywacz znalazły się w pamięci. Należy potem jedynie wykonać funkcję.
USR(play, nr_muzyczki, musadr)
gdzie play jest jak poprzednio adresem odgrywacza, musadr jest adresem danych songu, a nr_muzyczki liczymy od 1. dla mnie wprawnych problemem może być załadowanie plików CMC i REP do pamięci z Basicu, oraz przeliczenie adresów szesnastkowych (podawanych w CMC) na dziesiętne potrzebne jako parametry funkcji USR. Dla nich właśnie napisany został program przykładowy DEMO.BAS. została tam zaimplementowana pożyteczna funkcja BGET. Jest to procedura maszynowa ładująca dowolny plik. Jej kod umieszczony zostaje w pamięci w wierszu 10. użycie jest bardzo proste. Wystarczy otworzyć kanał do odczytu z dowolnego urządzenia (wiersz 1010) i można wywołać procedurę BGET, oczywiście przez funkcję USR. Dodatkową zaletą zaimplementowanego BGETu jest zwracanie adresu ładowanego pliku. Po wywołaniu funkcji X=USR(BGET) nie tylko ładowany jest otworzony do odczytu plik, lecz na dodatek zmienna X przyjmuje wartość adresu ładowania (potrzebną do późniejszego wywołania odgrywania). Uzupełnijmy wiadomości dotyczące odgrywania muzyczek z Basicu. Wykonanie funkcji USR z tylko jednym parametrem – USR(play) powoduje odinstalowanie grającego VBLANKu. Bezwzględnie nei wolno dwukrotnie założyć przerwania bez jego odinstalowania!!!
Jeżeli poprzednie dwa akapity okazały się zbyt trudne, to mam nadzieję, że garść poniższych wskazówek pozwoli każdemu dołączyć do własnego programu w BASICu dowolną muzyczkę. Aby dane odgrywacza i muzyczki nie kolidowały z basicem, należy umieszczać je zaraz pod pamięcią ekranu. CMC podaje adres początkowy i końcowy danych. Należy więc tak podać adres muzyczki (CONTROL A), by po przejściu później do procedury nagrywającej moduł odtwarzający (CONTROL M) koniec modułu wypadał poniżej 9c00. Jeżeli okaże się, że adres ten jest zbyt wysoki lub zbyt niski, należy wrócić do głównego okienka przez naciśnięcie ESC i próbować ustawić adres muzyczki (CONTROL A) nieco inaczej. Adres odgrywaczki jest ustawiany automatycznie zaraz za danymi muzyczki, więc koniec wszystkich danych przesunie się automatycznie. Bezpiecznym dla krótkich programów basicowych wydaje się adres muzyczki ustawiony na $8000. jeszcze garść wskazówek co do ładowania nagranej muzyczki i odgrywacza do pamięci. Aby we własnym programie uruchomić muzyczkę należy przenieść do niego wiersze 10–60 z programu przykładowego oraz podprogramik zaczynający się od wiersza 1000. Co za tym idzie nasz własny program powinien zawierać się między wierszami 61 a 999. Gdy chcemy załadować własną muzyczkę należy w wierszach 30 i 50 podać prawidłowe nazwy muzyczki i odgrywacza. Dla kasety będzie to C:. Należy jeszcze zwrócić uwagę, by oba pliki były nagrane na kasecie we właściwej kolejności jeden za drugim. Później w dowolnym miejscu programu wystarczy przepisać zawartość wiersza 510 i w momencie jego wykonania powinny zacząć dobywać się dźwięki.
|